﻿using System;
using System.Data;
using System.Configuration;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace TicTacToe
{
    public partial class BoardControl : System.Web.UI.UserControl
    {
        public event BoardCommandEventHandler BoardGameComplete;

        protected virtual void OnBoardGameComplete(BoardEventArgs e)
        {
            if (BoardGameComplete != null)
            {
                BoardGameComplete(this, e);
            }
        }

        public string PlayerSymbol
        {
            get
            {
                return "X";
            }
        }

        public string ComputerSymbol
        {
            get
            {
                return "0";
            }
        }

        public Board Board
        {
            get
            {
                object board = ViewState["_Board"];
                if (board == null)
                {
                    Board b = new Board();
                    ViewState["_Board"] = b;
                    return b;
                }
                else
                {
                    return (Board)board;
                }
            }
            private set
            {
                ViewState["_Board"] = value;
            }
        }

        private string GetImageUrlForPlayer(BoardPlayer player)
        {
            string imageUrl = string.Empty;
            switch (player)
            {
                case BoardPlayer.NoPlayer:
                    imageUrl = "Images/empty.jpg";
                    break;
                case BoardPlayer.Player:
                    imageUrl = "Images/X.jpg";
                    break;
                case BoardPlayer.Computer:
                    imageUrl = "Images/O.jpg";
                    break;
            }

            return imageUrl;
        }

        private void RestoreControlFromBoard(Board board)
        {
            int i = 1;
            foreach (BoardPlayer player in board)
            {
                ImageButton btn = (ImageButton)FindControl(string.Format("btnPosition{0}", i));
                btn.ImageUrl = GetImageUrlForPlayer(player);

                if (player != BoardPlayer.NoPlayer)
                {
                    btn.Enabled = false;
                }

                i++;
            }
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                RestoreControlFromBoard(Board);
            }
        }

        protected void btnPosition_Click(object sender, ImageClickEventArgs e)
        {
            ImageButton btn = (ImageButton)sender;
            int id = Convert.ToInt32(btn.ID.Substring(11)) - 1;

            try
            {
                BoardManager.MakeMoveOnBoard(Board, BoardPlayer.Player, id);
                btn.ImageUrl = GetImageUrlForPlayer(BoardPlayer.Player);
                btn.Enabled = false;

                MakeComputerMove();
                if (BoardManager.IsGameComplete(Board))
                {
                    OnBoardGameComplete(new BoardEventArgs(BoardManager.GetWinnder(Board)));
                    EnableButtons(false);
                }
            }
            catch (Exception)
            {
                OnBoardGameComplete(new BoardEventArgs(BoardManager.GetWinnder(Board)));
                EnableButtons(false);
            }
        }

        private void EnableButtons(bool enable)
        {
            for (int i = 1; i <= 9; i++)
            {
                ImageButton btn = (ImageButton)FindControl(string.Format("btnPosition{0}", i));
                btn.Enabled = enable;
            }
        }

        public void Reset()
        {
            Board = new Board();
            RestoreControlFromBoard(Board);
            EnableButtons(true);
        }

        public void MakeComputerMove()
        {
            MakeComputerMove(false);
        }

        public void MakeComputerMove(bool random)
        {
            int position = 0;
            if (random)
            {
                position = BoardManager.ComputeRandomMove();
            }
            else
            {
                position = BoardManager.ComputeBestMove(Board);
            }

            BoardManager.MakeMoveOnBoard(Board, BoardPlayer.Computer, position);
            ImageButton btn = (ImageButton)FindControl(string.Format("btnPosition{0}", position + 1));
            btn.ImageUrl = GetImageUrlForPlayer(BoardPlayer.Computer);
            btn.Enabled = false;
        }

        public class BoardEventArgs
        {
            private BoardPlayer winner;

            public BoardEventArgs(BoardPlayer player)
            {
                winner = player;
            }

            public BoardPlayer Winner
            {
                get
                {
                    return winner;
                }
            }
        }

        public delegate void BoardCommandEventHandler(object sender, BoardEventArgs e);
    }
}